from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify
import pymysql
from pymysql.cursors import DictCursor
from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps
import os, json, random

app = Flask(__name__)
app.secret_key = "my_super_secret_key_123"

# 数据库配置
LOCAL_DB_CONFIG = {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "123456",
    "database": "user_system",
    "charset": "utf8mb4",
    "cursorclass": DictCursor
}

# 单词系统配置
WORDS_FOLDER = 'word'
MARK_FILE = 'marked_words.json'


# ----------- 登录保护装饰器 ----------- #
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'username' not in session:
            flash("请先登录", "warning")
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated_function


# ----------- 数据库连接 ----------- #
def get_db_connection():
    return pymysql.connect(**LOCAL_DB_CONFIG)


# ----------- 首页 ----------- #
@app.route('/')
def home():
    return render_template('index.html')


# ----------- 登录 ----------- #
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        connection = get_db_connection()
        try:
            with connection.cursor() as cursor:
                sql = "SELECT * FROM users WHERE username = %s"
                cursor.execute(sql, (username,))
                user = cursor.fetchone()

                if user and check_password_hash(user['password_hash'], password):
                    session['username'] = user['username']
                    flash('登录成功！', 'success')
                    return redirect(url_for('dashboard'))
                else:
                    flash('用户名或密码错误', 'danger')
        finally:
            connection.close()

    return render_template('login.html')


# ----------- 注册 ----------- #
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        email = request.form['email']
        password = request.form['password']
        confirm_password = request.form['confirm_password']

        if password != confirm_password:
            flash("两次密码不匹配！", "danger")
            return redirect(url_for('register'))

        hashed_password = generate_password_hash(password)

        try:
            connection = get_db_connection()
            with connection.cursor() as cursor:
                sql = "INSERT INTO users (username, email, password_hash) VALUES (%s, %s, %s)"
                cursor.execute(sql, (username, email, hashed_password))
            connection.commit()
            flash("注册成功，请登录！", "success")
            return redirect(url_for('login'))
        except pymysql.MySQLError as e:
            flash(f"注册失败: {str(e)}", "danger")
        finally:
            connection.close()

    return render_template('register.html')


# ----------- 登出 ----------- #
@app.route('/logout')
def logout():
    session.clear()
    flash("已退出登录", "info")
    return redirect(url_for('home'))


# ----------- 用户主页（登录后） ----------- #
@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', username=session['username'])


# ----------- 用户中心 ----------- #
@app.route('/profile')
@login_required
def profile():
    return render_template('profile.html', username=session['username'])


# ----------- 修改密码 ----------- #
@app.route('/update_password', methods=['POST'])
@login_required
def update_password():
    username = session['username']
    current_password = request.form['current_password']
    new_password = request.form['new_password']
    confirm_password = request.form['confirm_password']

    connection = get_db_connection()
    try:
        with connection.cursor() as cursor:
            sql = "SELECT password_hash FROM users WHERE username = %s"
            cursor.execute(sql, (username,))
            user = cursor.fetchone()

            if not user or not check_password_hash(user['password_hash'], current_password):
                flash('当前密码不正确', 'danger')
                return redirect(url_for('profile'))

            if new_password != confirm_password:
                flash('新密码和确认密码不一致', 'danger')
                return redirect(url_for('profile'))

            new_hashed_password = generate_password_hash(new_password)
            update_sql = "UPDATE users SET password_hash = %s WHERE username = %s"
            cursor.execute(update_sql, (new_hashed_password, username))
            connection.commit()

            flash('密码修改成功', 'success')
            return redirect(url_for('profile'))
    finally:
        connection.close()


# ----------------------------
# -------- 记单词系统 --------
# ----------------------------

# 记单词主页面
@app.route('/words')
@login_required
def words_page():
    return render_template('words.html')


# 列出所有单词书
@app.route('/list_books')
@login_required
def list_books():
    books = [f for f in os.listdir(WORDS_FOLDER) if f.endswith('.json')]
    return jsonify({"books": books})


# 获取随机单词
@app.route('/get_word')
@login_required
def get_word():
    book = request.args.get("book")
    path = os.path.join(WORDS_FOLDER, book)

    words = []
    with open(path, 'r', encoding='utf-8') as f:
        for line in f:
            try:
                word_entry = json.loads(line)
                words.append(word_entry)
            except json.JSONDecodeError as e:
                print("解析失败：", e)

    word_entry = random.choice(words)
    # 获取词头
    word = word_entry.get("headWord") or word_entry.get("content", {}).get("word", {}).get("wordHead")

    return jsonify({
        "word": word,
        "full": word_entry
    })




# 标记单词（记住/不记住）
@app.route('/mark_word', methods=['POST'])
@login_required
def mark_word():
    data = request.form
    book = data.get("book")
    word = data.get("word")
    status = data.get("status")

    if os.path.exists(MARK_FILE):
        with open(MARK_FILE, 'r', encoding='utf-8') as f:
            marks = json.load(f)
    else:
        marks = {}

    if book not in marks:
        marks[book] = {}

    marks[book][word] = status

    with open(MARK_FILE, 'w', encoding='utf-8') as f:
        json.dump(marks, f, ensure_ascii=False, indent=2)

    return "OK"


# ----------------------------
# 启动
# ----------------------------
if __name__ == '__main__':
    app.run(debug=True)
